package com.lxbw.chain.service;

import com.lxbw.chain.config.LxbwConfig;
import com.lxbw.chain.entity.Kitty;
import com.lxbw.chain.model.KittyCore;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.web3j.crypto.Credentials;
import org.web3j.protocol.Web3j;
import org.web3j.protocol.core.methods.response.TransactionReceipt;
import org.web3j.tuples.generated.Tuple10;
import org.web3j.tx.ClientTransactionManager;
import org.web3j.tx.TransactionManager;

import java.math.BigInteger;


@Service
public class KittyCoreService {
    public static final BigInteger GAS_PRICE = BigInteger.valueOf(20_000_000_000L);
    public static final BigInteger GAS_LIMIT = BigInteger.valueOf(6_300_000);

    @Autowired
    private LxbwConfig lxbwConfig;

    @Autowired
    private Web3j web3j;

    public String name(String contractAddr) throws Exception {
        return loadForLookup(contractAddr).name().send();
    }

    public String symbol(String contractAddr) throws Exception {
        return loadForLookup(contractAddr).symbol().send();
    }

    public boolean paused(String contractAddr) throws Exception {
        return loadForLookup(contractAddr).paused().send();
    }


    private KittyCore loadForLookup(String contractAddr) {
        Credentials credentials = Credentials.create(lxbwConfig.getFromPrivatekey(), lxbwConfig.getFromAddress());
        return KittyCore.load(contractAddr, web3j, credentials, GAS_PRICE, GAS_LIMIT);
    }

    private KittyCore load(String contractAddr, String from) {
        TransactionManager txm = new ClientTransactionManager(web3j, from);
        return KittyCore.load(contractAddr, web3j, txm, GAS_PRICE, GAS_LIMIT);
    }

    public String ceoAddr(String contractAddr) throws Exception {
        return loadForLookup(contractAddr).ceoAddress().send();
    }

    public Kitty getKitty(String contractAddr, BigInteger idx) throws Exception {
        Tuple10<Boolean, Boolean, BigInteger, BigInteger, BigInteger, BigInteger, BigInteger, BigInteger, BigInteger, BigInteger> kittyObj =
                loadForLookup(contractAddr).getKitty(idx).send();

        return Kitty.from(kittyObj);
    }

    public String createPromoKitty(String contractAddr, String from, BigInteger genes) throws Exception {
        TransactionReceipt tx = load(contractAddr, from).createPromoKitty(genes, from).send();
        return tx.getTransactionHash();
    }
}
